/** 骨架屏组件（skeleton） **/

import { ChangeDetectionStrategy, Component, Directive, ElementRef, Input, OnChanges, OnInit, SimpleChanges } from '@angular/core';
import {
  ApesSkeletonAvatarShape,
  ApesSkeletonAvatarSize,
  ApesSkeletonButtonShape,
  ApesSkeletonButtonSize,
  ApesSkeletonInputSize,
  ApesSkeletonParagraphSize,
  ApesSkeletonType
} from './apes-skeleton.common';
import { ApesSizeMap,toCssPixel } from '@shared/apes/core';



@Directive({
  selector: 'apes-skeleton-element',
})
export class ApesSkeletonElementDirective {
  @Input() apesType: ApesSkeletonType = 'default';

  constructor(private elementRef: ElementRef) {
    this.elementRef.nativeElement.classList.add('apes-component');
  }
}

@Component({
  changeDetection: ChangeDetectionStrategy.OnPush,
  selector: 'apes-skeleton-element[apesType="default"]',
  template: `
    <div class="apes-skeleton"
         [ngClass]="apesClass"
         [ngStyle]="apesStyle"
         [style.height]="toCSSUnit(apesHeight)"
         [style.width]="toCSSUnit(apesWidth)"></div>
  `
})
export class ApesSkeletonElementDefaultComponent {
  @Input() apesClass: any;
  @Input() apesStyle: any;
  @Input() apesWidth: number | string;
  @Input() apesHeight: number | string = '1rem';

  toCSSUnit(value: number | string = ''): string {
    return toCssPixel(value);
  }
}

@Component({
  changeDetection: ChangeDetectionStrategy.OnPush,
  selector: 'apes-skeleton-element[apesType="button"]',
  template: `
    <div
      class="apes-skeleton apes-skeleton-button"
      [ngClass]="skeletonButtonClass()"
    ></div>
  `
})
export class ApesSkeletonElementButtonComponent {
  @Input() apesClass: any;
  @Input() apesShape: ApesSkeletonButtonShape = null;
  @Input() apesSize: ApesSkeletonButtonSize = null;

  skeletonButtonClass() {
    const sizeMap: ApesSizeMap = {large: 'lg', small: 'sm'};
    return {
      [`apes-skeleton-button-${this.apesShape}`]: this.apesShape,
      [`apes-skeleton-button-${sizeMap[this.apesSize]}`]: this.apesSize,
    };
  }
}

@Component({
  changeDetection: ChangeDetectionStrategy.OnPush,
  selector: 'apes-skeleton-element[apesType="avatar"]',
  template: `
    <div
      class="apes-skeleton apes-skeleton-avatar"
      [ngClass]="skeletonAvatarClass()"
      [ngStyle]="styleMap"
    ></div>
  `
})
export class ApesSkeletonElementAvatarComponent implements OnChanges {
  @Input() apesClass: any;
  @Input() apesShape: ApesSkeletonAvatarShape = 'circle';
  @Input() apesSize: ApesSkeletonAvatarSize = null;

  styleMap: any = {};

  ngOnChanges(changes: SimpleChanges): void {
    if (changes.apesSize && typeof this.apesSize === 'number') {
      const sideLength = `${this.apesSize}px`;
      this.styleMap = {width: sideLength, height: sideLength, 'line-height': sideLength};
    } else {
      this.styleMap = {};
    }
  }

  skeletonAvatarClass() {
    const sizeMap: ApesSizeMap = {large: 'lg', small: 'sm', extraSmall: 'xs'};
    return {
      [`apes-skeleton-avatar-${this.apesShape}`]: this.apesShape,
      [`apes-skeleton-avatar-${sizeMap[this.apesSize]}`]: this.apesSize,
    };
  }
}

@Component({
  changeDetection: ChangeDetectionStrategy.OnPush,
  selector: 'apes-skeleton-element[apesType="input"]',
  template: `
    <div
      class="apes-skeleton apes-skeleton-input"
      [ngClass]="skeletonInputClass()"
      [style.height]="toCSSUnit(apesHeight)"
      [style.width]="toCSSUnit(apesWidth)"
    ></div>
  `
})
export class ApesSkeletonElementInputComponent {
  @Input() apesClass: any;
  @Input() apesSize: ApesSkeletonInputSize = null;
  @Input() apesWidth: number | string;
  @Input() apesHeight: number | string;

  skeletonInputClass() {
    const sizeMap: ApesSizeMap = {large: 'lg', small: 'sm'};
    return {
      [`apes-skeleton-input-${sizeMap[this.apesSize]}`]: this.apesSize,
    };
  }

  toCSSUnit(value: number | string = ''): string {
    return toCssPixel(value);
  }
}

@Component({
  changeDetection: ChangeDetectionStrategy.OnPush,
  selector: 'apes-skeleton-element[apesType="image"]',
  template: `
    <div class="apes-skeleton apes-skeleton-image" [ngClass]="skeletonImageClass()">
      <svg class="apes-skeleton-image-svg" viewBox="0 0 1098 1024" xmlns="http://www.w3.org/2000/svg">
        <path
          d="M365.714286 329.142857q0 45.714286-32.036571 77.677714t-77.677714 32.036571-77.677714-32.036571-32.036571-77.677714 32.036571-77.677714 77.677714-32.036571 77.677714 32.036571 32.036571 77.677714zM950.857143 548.571429l0 256-804.571429 0 0-109.714286 182.857143-182.857143 91.428571 91.428571 292.571429-292.571429zM1005.714286 146.285714l-914.285714 0q-7.460571 0-12.873143 5.412571t-5.412571 12.873143l0 694.857143q0 7.460571 5.412571 12.873143t12.873143 5.412571l914.285714 0q7.460571 0 12.873143-5.412571t5.412571-12.873143l0-694.857143q0-7.460571-5.412571-12.873143t-12.873143-5.412571zM1097.142857 164.571429l0 694.857143q0 37.741714-26.843429 64.585143t-64.585143 26.843429l-914.285714 0q-37.741714 0-64.585143-26.843429t-26.843429-64.585143l0-694.857143q0-37.741714 26.843429-64.585143t64.585143-26.843429l914.285714 0q37.741714 0 64.585143 26.843429t26.843429 64.585143z"
          class="apes-skeleton-image-path"
        />
      </svg>
    </div>
  `
})
export class ApesSkeletonElementImageComponent {

  @Input() apesSize: ApesSkeletonInputSize = null;

  skeletonImageClass() {
    const sizeMap: ApesSizeMap = {large: 'lg', small: 'sm'};
    return {
      [`apes-skeleton-image-${sizeMap[this.apesSize]}`]: this.apesSize,
    };
  }
}


@Component({
  changeDetection: ChangeDetectionStrategy.OnPush,
  selector: 'apes-skeleton-element[apesType="paragraph"]',
  template: `
    <ul>
      <li *ngFor="let row of rowsList; let i = index"
          class="apes-skeleton apes-skeleton-paragraph"
          [ngClass]="skeletonParagraphClass()"
          [style.height]="toCSSUnit(apesHeight)"
          [style.width]="toCSSUnit(row['width'])"></li>
    </ul>
  `
})
export class ApesSkeletonElementParagraphComponent implements OnInit {
  @Input() apesClass: any;
  @Input() apesSize: ApesSkeletonParagraphSize = null;
  @Input() apesWidth: number | string;
  @Input() apesHeight: number | string;
  @Input() apesRow: number = 3;

  rowsList: number[] = [];

  ngOnInit(): void {
    this.updateProps();
  }

  updateProps() {
    let num = this.apesRow;
    let width = this.apesWidth ? this.apesWidth : '80%';
    this.rowsList = [];
    for (let i = 1; i <= num; i++) {
      let rows: any = {row: i, width: width};
      if (i == num) {
        rows.width = '50%';
      }
      this.rowsList.push(rows);
    }
  }

  skeletonParagraphClass() {
    const sizeMap: ApesSizeMap = {large: 'lg', small: 'sm'};
    return {
      [`apes-skeleton-paragraph-${sizeMap[this.apesSize]}`]: this.apesSize,
    };
  }

  toCSSUnit(value: number | string = ''): string {
    return toCssPixel(value);
  }
}
